﻿using CaseManagerLibrary.Log;
using CaseManagerLibrary.Models;
using NetSDKCS;
using PSDLib.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSDLib.Download
{
    public class DaHuaDownloadServer : IDownloadServer
    {
        private static fDisConnectCallBack m_DisConnectCallBack;
        private static fHaveReConnectCallBack m_ReConnectCallBack;
        public NET_DEVICEINFO_Ex m_DeviceInfo;
        public IntPtr m_LoginID;

        public event EventHandler OnDisConnect;
        public event EventHandler OnReConnect;

        public string ID { get; set; }
        public string Name { get; set; }
        public ILog Logger { get; set; }
        public string ServerIP { get; set; }
        public int ServerPort { get; set; }
        public string ServerUser { get; set; }
        public string ServerPassword { get; set; }

        private bool online = false;
        private static object lock_online = new object();
        List<ChannelInfo> channelList = new List<ChannelInfo>();

        public bool Online
        {
            get
            {
                lock (lock_online)
                {
                    return online;
                }
            }
            set
            {
                lock (lock_online)
                {
                    online = value;
                }
            }
        }

        private bool resetting = false;

        public DaHuaDownloadServer()
        {
            Logger = new ConsoleLog();
            Logger.BringToFront = false;
        }

        public void Cleanup()
        {
            try
            {
                Logout();

                DaHuaNetClient.Cleanup();

                Logger.Info("清理DaHua SDK资源");
            }
            catch (Exception ex)
            { }
        }

        public bool Init()
        {
            bool success = false;
            try
            {
                m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack);
                m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack);

                //初始化大华NETCLIENT SDK
                DaHuaNetClient.Init(m_DisConnectCallBack, IntPtr.Zero, null);
                DaHuaNetClient.SetAutoReconnect(m_ReConnectCallBack, IntPtr.Zero);

                success = true;
                Logger.Info("【" + Name + "】初始化DaHua SDK成功");

            }
            catch (Exception ex)
            {
                success = false;
                Logger.Error("【" + Name + "】初始化DaHua SDK失败：" + ex.Message);
            }

            return success;
        }

        private void DisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
        {
            Online = false;

            if (Logger != null)
            {
                Logger.Info("下载服务器连接中断");
            }

            if (!resetting)
            {
                OnDisConnect?.Invoke(this, null);
            }

            return;
        }

        private void ReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser)
        {
            Online = true;

            if (Logger != null)
            {
                Logger.Info("下载服务器重新连接");
            }

            if (!resetting)
            {
                OnReConnect?.Invoke(this, null);
            }

            return;
        }

        public bool Login()
        {
            bool success = false;

            //登录大华存储设备
            m_DeviceInfo = new NET_DEVICEINFO_Ex();

            m_LoginID = DaHuaNetClient.LoginWithHighLevelSecurity(ServerIP,
                (ushort)ServerPort,
                ServerUser,
                ServerPassword,
                EM_LOGIN_SPAC_CAP_TYPE.TCP,
                IntPtr.Zero,
                ref m_DeviceInfo);

            if (IntPtr.Zero == m_LoginID)
            {
                Online = false;
                success = false;
                Logger.Error("登录存储设备失败：" + DaHuaNetClient.GetLastError());
            }
            else
            {
                Online = true;
                success = true;
                Logger.Info("登录存储设备成功");
            }

            return success;
        }

        public bool ReLogin()
        {
            bool success = false;

            resetting = true;

            Cleanup();

            if (Init())
            {
                success = Login();
            }
            else
            {
                success = false;
            }

            resetting = false;

            return success;
        }

        public void Logout()
        {
            try
            {
                if (m_LoginID != IntPtr.Zero)
                {
                    bool result = DaHuaNetClient.Logout(m_LoginID);

                    m_LoginID = IntPtr.Zero;

                    Logger.Info("登出存储设备：" + result.ToString());
                }
            }
            catch { }
            finally
            {
                Online = false;
            }
        }

        public IDownloader CreateDownload(dl_files file)
        {
            //创建大华存储设备下载器
            var dh_downloader = new DH_EVS_Downloader();
            dh_downloader.m_LoginID = m_LoginID;
            dh_downloader.m_DeviceInfo = m_DeviceInfo;
            dh_downloader.Id = file.id;
            dh_downloader.Logger = Logger;
            dh_downloader.DownloadServer = this;

            return dh_downloader;
        }

        public void ResetSessionInfo(IDownloader downloader)
        {
            if (downloader != null)
            {
                downloader.ResetSessionInfo(m_LoginID, m_DeviceInfo);
            }
        }

        public string GetLastError()
        {
            return DaHuaNetClient.GetLastError();
        }

        public List<ChannelInfo> GetChannelList()
        {
            channelList.Clear();

            if (online)
            {
                for (int i = 0; i < m_DeviceInfo.nChanNum; i++)
                {
                    var ch = new ChannelInfo();
                    ch.Id = i.ToString();
                    ch.Name = i.ToString();
                    ch.ServerId = this.ID;
                    channelList.Add(ch);
                }
            }

            return channelList;
        }
    }
}
